package com.godyao.framework.context.annotation;


import cn.hutool.core.util.StrUtil;
import com.godyao.framework.beans.factory.config.BeanDefinition;
import com.godyao.framework.beans.factory.support.BeanDefinitionRegistry;
import com.godyao.framework.stereotype.Component;
import com.godyao.framework.stereotype.Repository;
import com.godyao.framework.stereotype.Service;

import java.util.Set;

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
    private BeanDefinitionRegistry registry;

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
        this.registry = registry;
    }

    public void doScan(String... basePackages) {
        for (String basePackage : basePackages) {
            Set<BeanDefinition> candidateComponents = findCandidateComponents(basePackage);
            for (BeanDefinition candidateComponent : candidateComponents) {
                String beanScope = resolveBeanScope(candidateComponent);
                if (StrUtil.isNotBlank(beanScope)) {
                    candidateComponent.setScope(beanScope);
                }
                registry.registerBeanDefinition(determineBeanName(candidateComponent), candidateComponent);

            }
        }
    }

    private String determineBeanName(BeanDefinition candidateComponent) {
        Class beanClass = candidateComponent.getBeanClass();
        String beanName= "";
        if (beanClass.isAnnotationPresent(Component.class)) {
            Component component = (Component) beanClass.getAnnotation(Component.class);
            beanName = component.value();
        }
        if (beanClass.isAnnotationPresent(Service.class)) {
            Service service = (Service) beanClass.getAnnotation(Service.class);
            beanName = service.value();
        }
        if (beanClass.isAnnotationPresent(Repository.class)) {
            Repository repository = (Repository) beanClass.getAnnotation(Repository.class);
            beanName = repository.value();
        }

        if (StrUtil.isBlank(beanName)) {
            beanName = StrUtil.lowerFirst(beanClass.getSimpleName());
        }
        return beanName;


    }

    private String resolveBeanScope(BeanDefinition candidateComponent) {
        Scope scope = (Scope)candidateComponent.getBeanClass().getAnnotation(Scope.class);
        if (null != scope) return scope.value();
        return StrUtil.EMPTY;
    }
}
